﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using Cubicle.Core.Interfaces;

namespace Cubicle.Core.Processors.Parameter
{
    [Export("Cubicle.Processors.Parameter.JaggedArrayParameterResolver", typeof(IProcessor<ParameterRequest>))]
    [ExportMetadata("Name", "JaggedArrayParameterResolver")]
    [ExportMetadata("Description", "Resolves a parameter to a Jagged array.")]
    public class JaggedArrayParameterResolver : ConditionalProcessor<ParameterRequest>
    {

        [Import]
        private ParameterProcessor _parProcessor;

        public override bool Condition(ParameterRequest request)
        {
            var valueType = request.SourceType;
            return valueType.IsArray
                   && valueType.GetElementType().IsArray
                   && request.TargetType.IsArray
                   && request.TargetType.GetElementType().IsArray;
        }

        public override ParameterRequest ConditionalProcess(ParameterRequest request)
        {
            var elemType = request.TargetType.GetElementType();
            if (request.Source.GetType().GetElementType() == elemType)
                request.Complete(request.Source);

            // Initialise result
            var valueArr = request.Source as Array;
            var result = new object[valueArr.Length];
            for (var i = 0; i < valueArr.Length; i++)
            {
                var slice = valueArr.GetValue(i) as Array;
                var requests = new List<ParameterRequest>();
                for (int j = 0; j < valueArr.Length; j++) requests.Add(new ParameterRequest(elemType, slice.GetValue(j)));
                result = requests.Select(x => _parProcessor.Process(x)).Select(x => x.Result).ToArray();
            }

            request.Complete(result);
            return request;
        }

    }
}